package acadclockmidletpkg;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.DataInputStream;
import java.io.DataOutputStream;
import java.io.IOException;
import java.util.Date;
import javax.microedition.rms.RecordStore;
import javax.microedition.rms.RecordStoreException;

/**
 * Класс, инкапсулирующий функциональность создания и работы с RMS-хранилищем
 * значений настроек программы.
 *
 * @author Kolomoets G.P.
 * @version 1.0
 */
public class RMSWorker {

    public static final String nameDB = "AcademicClockSettings";
    public static AcademicClockRecord record = new AcademicClockRecord();
    private RecordStore rs;

    public RMSWorker() {
        this.rs = null;
    }

    /**
     * Инициализация хранилища записей. Для пустой базы создаётся одна запись с
     * текущими датой, временем и значением длительности пар по-умолчанию - 75
     * мин. Если количество записей превышает 1, база очищается. Если количество
     * записей равно 1 - ничего не делается.
     */
    public void initializeRecordStore() {
        try {
            rs = RecordStore.openRecordStore(nameDB, true);
            int numRecords = rs.getNumRecords();
            //Отладочный вывод
            System.out.println("Last Records ID is: " + (rs.getNextRecordID() - 1));
            /*Для пустой базы*/
            if (numRecords == 0) {
                saveRecord(record); //recordId=1
                closeRecordStore();
                /*Для базы с количеством записей не равным 1*/
            } else if (rs.getNextRecordID() != 2) {
                closeRecordStore();
                RecordStore.deleteRecordStore(nameDB);
            }
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        }
        record = readDateRecord(1);
    }

    /**
     * Закрытие хранилища.
     */
    public void closeRecordStore() {
        try {
            if (rs != null) {
                rs.closeRecordStore();
            }
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        }
    }

    /**
     * Сохранение значений даты и/или времени в базе.
     *
     * @param savedRacord - записб со значениями из формы настроеек
     * @return идентификатор записи
     */
    public int saveRecord(AcademicClockRecord savedRacord) {
        int recordId = 0;
        ByteArrayOutputStream baout = new ByteArrayOutputStream();
        DataOutputStream dout = new DataOutputStream(baout);
        try {
            RecordStore.openRecordStore(nameDB, false);
            writeDout(dout, savedRacord);
            byte[] data = baout.toByteArray();
            recordId = rs.addRecord(data, 0, data.length);
            dout.close();
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        closeRecordStore();
        return recordId;
    }

    /**
     * Обновление значений записи в базе данных.
     *
     * @param updatedRecord - новое значение записи
     */
    public void updateRecord(int recordId, AcademicClockRecord updatedRecord) {
        ByteArrayOutputStream baout = new ByteArrayOutputStream();
        DataOutputStream dout = new DataOutputStream(baout);
        try {
            RecordStore.openRecordStore(nameDB, false);
            writeDout(dout, updatedRecord);
            byte[] data = baout.toByteArray();
            rs.setRecord(recordId, data, 0, data.length);
            record=updatedRecord;
            dout.close();
        } catch (IOException ex) {
            ex.printStackTrace();
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        }
        closeRecordStore();
    }

    /**
     * Чтение значений записи из базы данных.
     *
     * @param recordId идентификатор записи
     * @return запись со значениями настроек
     */
    public AcademicClockRecord readDateRecord(int recordId) {
//        AcademicClockRecord record = new AcademicClockRecord();
        Date date = new Date();
        String pairTime;
        byte[] data;
        ByteArrayInputStream bain;
        DataInputStream din;
        try {
            RecordStore.openRecordStore(nameDB, false);
            data = rs.getRecord(recordId);
            bain = new ByteArrayInputStream(data);
            din = new DataInputStream(bain);
            //TODO Рефвкторить методы установки в AcademicClockRecord чтобы здксь
            //упростить (провериь вначале используются ли они в простом виде 
            //где-нибудь)
//            date.setTime(din.readLong());
            long value1 = din.readLong();
            date.setTime(value1);
            record.getFirstSemesterBegin().setDate(date);
            System.out.println("first semester begin at " + record.getFirstSemesterBegin().getDate().getTime());
//            date.setTime(din.readLong());
            long value2 = din.readLong();
            date.setTime(value2);
            record.getSecondSemesterBegin().setDate(date);
            System.out.println("second semester begin at " + record.getSecondSemesterBegin().getDate().getTime());
            pairTime = din.readUTF();
            record.getPairDuration().setString(pairTime);
            System.out.println("pair duration is " + record.getPairDuration().getString());
            date.setTime(din.readLong());
            record.getFifthPairBegin().setDate(date);
            date.setTime(din.readLong());
            record.getSecondPairBegin().setDate(date);
            date.setTime(din.readLong());
            record.getThirdPairBegin().setDate(date);
            date.setTime(din.readLong());
            record.getFourthPairBegin().setDate(date);
            date.setTime(din.readLong());
            record.getFifthPairBegin().setDate(date);
            date.setTime(din.readLong());
            record.getSixthPairBegin().setDate(date);
            date.setTime(din.readLong());
            record.getSeventhPairBegin().setDate(date);
            date.setTime(din.readLong());
            record.getEighthPairBegin().setDate(date);
            date.setTime(din.readLong());
            record.getNinethPairBegin().setDate(date);
        } catch (RecordStoreException ex) {
            ex.printStackTrace();
        } catch (IOException ex) {
            ex.printStackTrace();
        }
        closeRecordStore();
        return record;
    }

    /**
     * Метод записи данных компонентов формы настроек в поток вывода данных.
     *
     * @param dout поток вывода данных из БД
     * @param record выводимая из БД запись
     * @throws IOException при ошибках записи в поток
     */
    private void writeDout(DataOutputStream dout, AcademicClockRecord record) throws IOException {
        dout.writeLong(record.getFirstSemesterBegin().getDate().getTime());
        dout.writeLong(record.getSecondPairBegin().getDate().getTime());
        dout.writeUTF(record.getPairDuration().getString());
        dout.writeLong(record.getFirstPairBegin().getDate().getTime());
        dout.writeLong(record.getSecondPairBegin().getDate().getTime());
        dout.writeLong(record.getThirdPairBegin().getDate().getTime());
        dout.writeLong(record.getFourthPairBegin().getDate().getTime());
        dout.writeLong(record.getFifthPairBegin().getDate().getTime());
        dout.writeLong(record.getSixthPairBegin().getDate().getTime());
        dout.writeLong(record.getSeventhPairBegin().getDate().getTime());
        dout.writeLong(record.getEighthPairBegin().getDate().getTime());
        dout.writeLong(record.getNinethPairBegin().getDate().getTime());
    }

//    public AcademicClockRecord getRecord() {
//        return record;
//    }
//
//    public void setRecord(AcademicClockRecord record) {
//        this.record = record;
//    }
}
